/*
	by Ilija
*/


#include "UTFont.h"
#include "../tinyxml/tinyxml.h"
#include <string>


void UTFont::reset()
{
    isLoaded = false;

	fileName = "";

	info.face = "";
	info.size = 0;
	info.bold = 0;
	info.italic = 0;
	info.charset = "";
	info.unicode = 0;
	info.stretchH = 0;
	info.smooth = 0;
	info.aa = 0;
	info.padding[0] = info.padding[1] = info.padding[2] = info.padding[3] = 0;
	info.spacing[0] = info.spacing[1] = 0;
	info.outline = 0;

	common.lineHeight = 0;
	common.base = 0;
	common.scaleW = 0;
	common.scaleH = 0;
	common.pages = 0;
	common.packed = 0;
	common.alphaChnl = 0;
	common.redChnl = 0;
	common.greenChnl = 0;
	common.blueChnl = 0;

	for (int i = 0; i < UTFONT_PAGES_COUNT; i++)
	{
		pages[i].id = i;
		pages[i].file = "";
	}

	for (int i = 0; i < UTFONT_CHARS_COUNT; i++)
	{
		chars[i].id = i;
		chars[i].x = 0;
		chars[i].y = 0;
		chars[i].width = 0;
		chars[i].height = 0;
		chars[i].xoffset = 0;
		chars[i].yoffset = 0;
		chars[i].xadvance = 0;
		chars[i].page = 0;
		chars[i].chnl = 0;
		for (int j = 0; j < UTFONT_CHARS_COUNT; j++)
		{
			chars[i].kernings[j] = 0;
		}
	}
}


void UTFont::loadFont(const char* file_name)
{
	TiXmlDocument doc(file_name);
	isLoaded = doc.LoadFile();

	if (isLoaded)
	{
        TiXmlElement* elem;
        TiXmlElement* root;
        TiXmlString str;

		if (fileName != "")
		{
			reset();
		}

		root = doc.FirstChildElement("font");

		//
		//info
		//
		elem = root->FirstChildElement("info");
		str = elem->Attribute("face");
			info.face = str.c_str();
		elem->QueryIntAttribute("size", &info.size);
		elem->QueryIntAttribute("bold", &info.bold);
		elem->QueryIntAttribute("italic", &info.italic);
		str = elem->Attribute("charset");
			info.charset = str.c_str();
		elem->QueryIntAttribute("unicode", &info.unicode);
		elem->QueryIntAttribute("stretchH", &info.stretchH);
		elem->QueryIntAttribute("smooth", &info.smooth);
		elem->QueryIntAttribute("aa", &info.aa);
		str = elem->Attribute("padding");
			/// TODO: parse padding
		str = elem->Attribute("spacing");
			/// TODO: parse spacing
		elem->QueryIntAttribute("outline", &info.outline);

		//
		//common
		//
		elem = root->FirstChildElement("common");
		elem->QueryIntAttribute("lineHeight", &common.lineHeight);
		elem->QueryIntAttribute("base", &common.base);
		elem->QueryIntAttribute("scaleW", &common.scaleW);
		elem->QueryIntAttribute("scaleH", &common.scaleH);
		elem->QueryIntAttribute("pages", &common.pages);
		elem->QueryIntAttribute("packed", &common.packed);
		elem->QueryIntAttribute("alphaChnl", &common.alphaChnl);
		elem->QueryIntAttribute("redChnl", &common.redChnl);
		elem->QueryIntAttribute("greenChnl", &common.greenChnl);
		elem->QueryIntAttribute("blueChnl", &common.blueChnl);

		//
		//pages
		//
		for (elem = root->FirstChildElement("pages")->FirstChildElement(); elem; elem = elem->NextSiblingElement())
		{
			int id;
			elem->QueryIntAttribute("id", &id);
				pages[id].id = id;
			str = elem->Attribute("file");
				pages[id].file = str.c_str();
		}

		//
		//chars
		//
		for (elem = root->FirstChildElement("chars")->FirstChildElement(); elem; elem = elem->NextSiblingElement())
		{
			int id;
			elem->QueryIntAttribute("id", &id);
			if (id >= 0 && id < UTFONT_CHARS_COUNT)
			{
				chars[id].id = id;
				elem->QueryIntAttribute("x", &chars[id].x);
				elem->QueryIntAttribute("y", &chars[id].y);
				elem->QueryIntAttribute("width", &chars[id].width);
				elem->QueryIntAttribute("height", &chars[id].height);
				elem->QueryIntAttribute("xoffset", &chars[id].xoffset);
				elem->QueryIntAttribute("yoffset", &chars[id].yoffset);
				elem->QueryIntAttribute("xadvance", &chars[id].xadvance);
				elem->QueryIntAttribute("page", &chars[id].page);
				elem->QueryIntAttribute("chnl", &chars[id].chnl);
			}
		}

		//
		//kernings
		//
		if (root->FirstChildElement("kernings"))
		for (elem = root->FirstChildElement("kernings")->FirstChildElement(); elem; elem = elem->NextSiblingElement())
		{
			int first, second, amount;
			elem->QueryIntAttribute("first", &first);
			elem->QueryIntAttribute("second", &second);
			elem->QueryIntAttribute("amount", &amount);
			if (first >= 0 && first < UTFONT_CHARS_COUNT &&
				second >= 0 && second < UTFONT_CHARS_COUNT)
			{
				chars[first].kernings[second] = amount;
			}
		}

		fileName = file_name;
	}
}


int UTFont::getStringWidth(const String& str)
{
	int x = 0;
	for (int i = 0; i < str.getLength(); i++)
	{
		int c = (int)str.getChar(i);
		x += chars[c].xadvance;
		if (i < str.getLength() - 1)
			x += chars[c].kernings[(int)str.getChar(i + 1)];
	}
	return x;
}


vector2i UTFont::getTextSize(const String& str)
{
	vector2i size(0, 0);
	int x = 0;
	for (int i = 0; i < str.getLength(); i++)
	{
		int c = (int)str.getChar(i);
		x += chars[c].xadvance;
		if (i < str.getLength() - 1)
		{
			if (c == '\n')
			{
				if (x > size.x)
					size.x = x;
				x = 0;
				size.y += common.lineHeight;
			}
			else
			{
				x += chars[c].kernings[(int)str.getChar(i + 1)];
			}
		}
	}
	if (x > size.x)
		size.x = x;
	size.y += common.lineHeight;
	return size;
}








